﻿using UnityEngine;
using System.Collections;

/// <summary>
/// Unity脚本C#的扩展函数类，方便对Unity脚本的使用
/// </summary>
public static class UnityExtension
{
    public delegate void VoidDelegate();

    static public void Freezing(this MonoBehaviour comp)
    {
        if (null == comp)
        {
            return;
        }

        comp.enabled = false;
    }

    /// <summary>
    /// Extension for Easy call
    /// </summary>
    /// <param name="comp"></param>
    /// <param name="duration"></param>
    /// <param name="del"></param>
    static public void WaitForSecondsExt(this MonoBehaviour comp, float duration, VoidDelegate del)
    {
        comp.StartCoroutine(DoWaitForSecondsExt(comp, duration, del, null));
    }

    /// <summary>
    /// Extension for Easy call
    /// </summary>
    /// <param name="comp"></param>
    /// <param name="frameCnt"></param>
    /// <param name="del"></param>
    static public void WaitForNextFramesExt(this MonoBehaviour comp, int frameCnt, VoidDelegate del)
    {
        comp.StartCoroutine(DoWaitForNextFrameExt(comp, frameCnt, del, null));
    }

    /// <summary>
    /// Extension for Easy call
    /// </summary>
    /// <param name="comp"></param>
    /// <param name="duration"></param>
    /// <param name="del"></param>
    /// <param name="update"></param>
    /// <returns></returns>
    static public IEnumerator DoWaitForSecondsExt(this MonoBehaviour comp, float duration, VoidDelegate del, VoidDelegate update)
    {
        while (duration > 0)
        {
            duration -= Time.deltaTime;
            if (update != null) update();
            yield return null;
        }

        if (del != null) del();
    }

    /// <summary>
    /// Extension for Easy call
    /// </summary>
    /// <param name="comp"></param>
    /// <param name="frameCnt"></param>
    /// <param name="del"></param>
    /// <param name="update"></param>
    /// <returns></returns>
    static public IEnumerator DoWaitForNextFrameExt(this MonoBehaviour comp, int frameCnt, VoidDelegate del, VoidDelegate update)
    {
        while (frameCnt > 0)
        {
            frameCnt--;
            if (update != null) update();
            yield return null;
        }

        if (del != null) del();
    }

#region Extend Restart
    static public void Restart(this Animation anim)
    {
        if (null != anim)
        {
            anim.Stop();
            anim.Play();
        }
    }

    static public void Restart(this Animator anim)
    {
        if (null != anim)
        {
            anim.StopPlayback();

            AnimatorStateInfo info = anim.GetCurrentAnimatorStateInfo(0);
            if (!info.Equals(default(AnimatorStateInfo)))
            {
                anim.Play(info.shortNameHash);
            }
        }
    }

    static public void Restart(this ParticleSystem particle)
    {
        if (null != particle)
        {
            // 此处 Clear与Stop都无法将特效完美停止
            // 使用Simulate + Play
            //particle.Clear();
            particle.Simulate(0f);
            //particle.Stop(true);
            particle.Play();
        }
    }

    static public void Restart(this TrailRenderer trail, MonoBehaviour comp)
    {
        if (null != comp && comp.enabled)
        {
            comp.StartCoroutine(RestartTrail(trail));
        }
    }

    static IEnumerator RestartTrail(TrailRenderer trail)
    {
        if (null == trail)
        {
            yield break;
        }

        float trailTime = trail.time;
        trail.time = 0;
        yield return null;

        trail.time = trailTime;
    }
#endregion Extend Restart
}